package com.tax.common.constant;

import com.alibaba.fastjson.JSON;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.modelmapper.ModelMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author 段德辉
 */
public abstract class RequestHolderUtil extends RequestContextHolder {

    private static final Logger logger = LoggerFactory.getLogger(RequestHolderUtil.class);

    private static final String UNKOWN="unknown";
    public static CommonHeader getCommonHeader(){
        Field[] declaredFields = CommonHeader.class.getDeclaredFields();
        Map<String,String> headerMap=new HashMap<>(16);
        if(declaredFields!=null){
            for (Field declaredField : declaredFields) {
                String name = declaredField.getName();
                String val = RequestHolderUtil.getHeaderVal(name);
                headerMap.put(name,val);
            }
        }

        ModelMapper modelMapper=new ModelMapper();
        CommonHeader commonHeader = modelMapper.map(headerMap, CommonHeader.class);
        if(commonHeader==null){
            commonHeader=new CommonHeader();
        }
        logger.info("getCommonHeader,commonHeader:{}", JSON.toJSONString(commonHeader));
        return commonHeader;
    }

    public static String getIp() {
        String ip="";
        try{
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = servletRequestAttributes.getRequest();
            ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || UNKOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || UNKOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || UNKOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || UNKOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || UNKOWN.equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            if (ip != null && ip.length() > 15)
            {
                if (ip.indexOf(",") > 0)
                {
                    ip = ip.substring(0, ip.indexOf(",")).trim();
                }
            }
        }catch (Exception e){
            logger.error("RequestHolderUtil getRequest {}",ExceptionUtils.getStackTrace(e));
        }
        return ip;
    }

    public static String getRequestHeader(String key){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpRequest = attributes.getRequest();
        String value = httpRequest.getHeader(key);
        return value;
    }

    public static String  getHeaderVal(String key) {
        try {
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = servletRequestAttributes.getRequest();
            String headerVal = request.getHeader(key);
            return headerVal;
        } catch (IllegalStateException e) {
            logger.error("RequestHolderUtil getHeaderVal {}", ExceptionUtils.getStackTrace(e));
            return "";
        }

    }

    public static Map<String, String> getHeaderMap() {
        try {
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = servletRequestAttributes.getRequest();
            Enumeration headerNames = request.getHeaderNames();
            Map<String, String> headers = new HashMap<>(16);
            while (headerNames.hasMoreElements()) {
                String headerName = (String) headerNames.nextElement();
                String headerValue = request.getHeader(headerName);
                headers.put(headerName, headerValue);
            }
            return headers;
        } catch (IllegalStateException e) {
            logger.error("RequestHolderUtil get {}", ExceptionUtils.getStackTrace(e));
            return null;
        }
    }


    public static String  get(String key) {
        try {
            Object o = currentRequestAttributes().getAttribute(key, RequestAttributes.SCOPE_REQUEST);
            if (o != null) {
                String val = (String) o;
                return val;
            }
        } catch (IllegalStateException e) {
            logger.error("RequestHolderUtil get {}",ExceptionUtils.getStackTrace(e));
            return "";
        }
        return "";
    }

    public static String getUserId(){
        return getHeaderVal(HeaderConst.USERID);
    }


    public static String  getAppVersion(){
        List<String> versionKeyList = HeaderConst.appVersionKeyList;
        String appVersion = getSampleValue(versionKeyList);
        return appVersion;
    }

    public static String  getDeviceId(){
        List<String> deviceIdKeyList = HeaderConst.deviceIdKeyList;
        String deviceId = getSampleValue(deviceIdKeyList);
        return deviceId;
    }

    public static String getToken(){
        return   getHeaderVal(HeaderConst.TOKENKEY);
    }

    public static String getAppsys(){
        return getHeaderVal(HeaderConst.APPSYS);
    }


    public static BaseHeader getBaseHeader() {
        BaseHeader baseHeader=new BaseHeader();

        String appVersion = getAppVersion();
        baseHeader.setAppVersion(appVersion);

        String deviceId = getDeviceId();
        baseHeader.setDeviceId(deviceId);

        String token = getToken();
        baseHeader.setToken(token);

        String appsys = getAppsys();
        baseHeader.setAppsys(appsys);
        return  baseHeader;
    }

    private static String getSampleValue(Collection<String> keyList) {
        if(keyList!=null&&!keyList.isEmpty()){
            for (String key : keyList) {
                String headerVal = getHeaderVal(key);
                if(StringUtils.isNotBlank(headerVal)){
                    return headerVal;
                }
            }
        }
        return "";
    }

    @Data
    public static class  BaseHeader{
        @ApiModelProperty("登录的端，tax-h5、tax-xcx、tax-pc、tax-wechat、tax-ios、tax-android")
        private String appsys;

        @ApiModelProperty("应用版本号appVersion")
        private String appVersion;

        @ApiModelProperty("设备id")
        private String deviceId;

        @ApiModelProperty("认证token")
        private String token;

    }
}